import { Plugin, EDITOR_ELEMENT_TYPE, PLUGINS_KEYS, commandType } from '../types';
import { Editor, Transforms } from 'slate';
import React from 'react';
import { getBlockMatch } from '@/core/utils/get';
import { isCollapsed, isMatchKeyDown, isFouceEnd } from '@/core/utils/is';
import { KEYDOWNS } from '@/core/types';
import { CustomElement } from '@/plugins/types';
import { DEFAULT_ELEMENT } from '../config';
import { setBlockNode } from '@/core/utils/set';

const command: commandType = (editor, key, data) => {
  setBlockNode(editor, {
    [key || PLUGINS_KEYS.HEADING]: data,
  });
};

function Heading(editor: Editor): Plugin {
  return {
    key: PLUGINS_KEYS.HEADING,
    type: EDITOR_ELEMENT_TYPE.BLOCK,
    match: (props) => !!props.element[PLUGINS_KEYS.HEADING],
    command,
    onKeyDown: (event) => {
      if (isCollapsed(editor) && isMatchKeyDown(event, KEYDOWNS.ENTER)) {
        const { block, path } = getBlockMatch(editor);
        if (!block[PLUGINS_KEYS.HEADING]) return null;
        if (isFouceEnd(editor, path)) {
          event.preventDefault();
          Transforms.insertNodes(editor, DEFAULT_ELEMENT as CustomElement);
        }
      }
    },
    render: (context) => {
      const config = context.props.element[PLUGINS_KEYS.HEADING];

      const level = config?.level;
      if (!level) throw new Error('Heading Plugin render Error');

      return React.createElement(`h${level}`, {}, context.children);
    },
  };
}

export default Heading;
